/*
 * init_appl.h
 *
 *  Created on: Jun 26, 2011
 *      Author: yzha
 *
 *  in order to use ACN protocol we need initial some configure at first . here some functions is used to  initial it.
 *  it will create two thread recv_funct and timer_funct . the first is for receiving message ,and the last is for making
 *  sure all connection is connected.
 */

#include <stdio.h>
#include <stdlib.h>

#include "opt.h"
#include "acnstdtypes.h"
#include "acn_port.h"
#include "acnlog.h"

#include "epi10.h"
#include "mcast_util.h" /* handy multicast utilities */
#include "ntoa.h"
#include "component.h"
#include "property.h"
#include "slp.h"
#include "discover.h"
#include "sdtmem.h"
#include "sdt.h"
#include "msleep.h"
#include "common_func.h"

#include "dmp.h"
#include "app_dmp.h"
#include <sys/time.h>
#include "init_appl.h"
#include "read_config.h"


/*****************************************************************************************/
/*
 * this section is modifed for each port */
char *dcid_str1 = "11111111-2222-3333-4444-aabbccddeeff";
char *cid_str1  = "11111111-2222-3333-4444-000000000000";
const char *myfctn = "ACN/BSD";
const char *myuacn = "Unit 1";
/*****************************************************************************************/

/* this section is the same for each port*/
component_t *local_component = NULL;
component_t *foreign_component = NULL;

pthread_t timer_thread_id;
pthread_t recv_thread_id;

char dmemLoc[NUM_CHANNEL][MAX_NAME];    //goble variable , the url of double memory location,readed by config files


void readConifgs(){
	int i = 0;
	char str[255] = "dmemLoc";
	char tmp[255] = "dmemLoc";
	for(;i<NUM_CHANNEL;i++){
		strcat(tmp,'1'+i);
		ReadConfig("/etc/config",tmp,dmemLoc[i]);
		strcpy(tmp,str);
	}
#ifdef _DEBUG
	printf("%s",dmemLoc);
#endif
}



/* Thread to receive data */
void *recv_funct(void *lParam)
{
 (void)(lParam);
  while (1) {
    /* test to see if we should cancel */
    pthread_testcancel();
    /* netx_poll is semi-blocking. It only returns to give app time to shut things down. */
    netx_poll();
  }
}

/* Thread to deal with timer (100ms) intervals */
void *timer_funct(void *lParam)
{
  (void)(lParam);
  /* call tick functions */
  while (1) {
    /* test to see if we should cancel */
    pthread_testcancel();
    slp_tick(NULL);
    sdt_tick(NULL);
    msleep(100); /* 100ms */
  }
}


void init_protcols_stack()
{
#if CONFIG_NSK
  srand(microsecsonds_since_midnight_GMT() + netx_getmyip(0));
  netx_init();
  netx_startup();
#endif

#if CONFIG_SLP
  slp_init();
  slp_open();
  slp_active_discovery_start();
#endif

#if CONFIG_RLP
  rlp_init();
#if CONFIG_SDT
  sdt_init();
  sdt_startup(true);
#endif

#endif //RLP
  printf("initial application success ,now starting threads ");
  pthread_create(&timer_thread_id, NULL, timer_funct, NULL);
  pthread_create(&recv_thread_id, NULL, recv_funct, NULL);

}


int init_component()
{
	/* netx_addr_t   addr; */
	ip4addr_t     myip = 0;
#if CONFIG_SDT
    cid_t cid;
    cid_t dcid;
#endif

#if CONFIG_NSK
  while (!myip) {
    myip = ntohl(netx_getmyip(NULL));
  }
#endif

#if CONFIG_SDT
  /* make a local component */
  textToCid(cid_str1, cid);
  textToCid(dcid_str1, dcid);
  /* make our cid unique to us */
  cid[15] = (uint8_t)(myip & 0xff);
  /* create our local component */
  local_component = sdt_add_component(cid, dcid, true, accBOTH, cbAPP);
  /* fill in some required data */
  if (local_component) {
    /* local_component->callback = component_callback; */
    strcpy(local_component->uacn, myuacn);
    strcpy(local_component->fctn, myfctn);
  }
#endif
  	//debug part
  	dmp_property_map_t *prop_new = NULL;
	uint16_t size = 2;
	uint32_t addr = 0x55;
	if((prop_new = property_new(addr,size))==NULL){
		printf("create property error \n");
		return -1;
	}else{
		printf("create property success \n");
	}
	display_property(prop_new);
	return 0;
}


void release_protcols_stack()
{
  /* shut things down - these require the threads to continue run... */
#if CONFIG_SDT
  sdt_shutdown();
#endif
#if CONFIG_SLP
  slp_close();
#endif
  /* close threads */
  pthread_cancel(recv_thread_id);
  pthread_join(recv_thread_id, NULL);
  pthread_cancel(timer_thread_id);
  pthread_join(timer_thread_id, NULL);
#if CONFIG_NSK
  netx_shutdown();
#endif
  slp_stats();
  sdt_stats();
  PRINTF("%s","========================\n");

  PRINTF("%s","Done...\n");
}








